﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Windows;

namespace WPFSchematics.Definition.Entities.Collection
{
    /// <summary>
    /// 通用实体集合类。该集合的元素具有持久且相同的所有者，
    /// 并且集合元素只能被某实体唯一拥有。
    /// </summary>
    /// <typeparam name="TMember">元素类型。</typeparam>
    public class MemberCollection<TMember> : DependencyObject, IEnumerable<TMember>,IOperateCollection
        where TMember:IEntity
    {
        private readonly List<TMember> _list = new List<TMember>(); //{ get { return (List<Member>)GetValue(ListProperty); } }

        public int Count
        {
            get { return _list.Count; }
        }

        public TMember this[int i]
        {
            get { return _list[i]; }
            set { _list[i] = value; }
        }

        public List<T> GetList<T>()
        {
            return _list.Select(m => (T) (object) m).ToList();
        }

        /// <summary>
        /// 
        /// </summary>
        public bool IsRebuildIndex { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="member"></param>
        public void Add(TMember member)
        {
            if (member != null && !_list.Contains(member))
            {
                _list.Add(member);
                RebuildIndex(_list.Count - 1);
                if (AttachOwner != null)
                {
                    AttachOwner(member);
                }
                
            }
        }

        public bool Contains(TMember member)
        {
            return _list.Contains(member);
        }

        private void RebuildIndex(int beginIndex)
        {
            if (!IsRebuildIndex) return;
            for (var i = beginIndex; i < _list.Count; i++)
            {
                _list[i].Index = i;
            }
        }

        public void Insert(int index, TMember member)
        {
            if (member != null && !_list.Contains(member))
            {
                _list.Insert(index, member);
                RebuildIndex(index);
                if (InsertOwner != null)
                {
                    InsertOwner(member,index);
                }
                
            }
        }

        public  void Remove(TMember member)
        {
            if (member != null && _list.Contains(member))
            {
                _list.Remove(member);
                RebuildIndex(member.Index);
                if (UnAttachOwner != null)
                {
                    UnAttachOwner(member);
                }
                
            }
        }

        public void Clear()
        {
            foreach (var member in _list.Where(member => UnAttachOwner != null))
            {
                UnAttachOwner(member);
            }
            _list.Clear();
        }

        #region IEnumerable<Member> 成员

        public IEnumerator<TMember> GetEnumerator()
        {
            return ((IEnumerable<TMember>) _list).GetEnumerator();
        }

        #endregion

        #region IEnumerable 成员

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion

        public delegate void AttachOwnerDlg(TMember member);
        public delegate void InsertOwnerDlg(TMember member,int index);
        public delegate void UnattachOwnerDlg(TMember member);

        public event AttachOwnerDlg AttachOwner;
        public event InsertOwnerDlg InsertOwner;
        public event UnattachOwnerDlg UnAttachOwner;
        
        public MemberCollection(AttachOwnerDlg attachOwner,UnattachOwnerDlg unattachOwner)
        {
            //if (owner == null)
            //    throw new NullReferenceException("初始化参数为空！");
            //SetValue(StaticOwnerEntityProperty, owner);

            if(attachOwner==null||unattachOwner==null)
                throw new NullReferenceException("初始化参数为空！");

            AttachOwner += attachOwner;
            UnAttachOwner += unattachOwner;
        }
        
        /// <summary>
        /// 
        /// </summary>
        public MemberCollection()
        {
            IsRebuildIndex = true;
        }
        
        public void Add(object member)
        {
            if (member is TMember)
            {
                Add((TMember)member);
            }
        }

        public void Remove(object member)
        {
            if (member is TMember)
            {
                Remove((TMember)member);
            }
        }


        public void Insert(int index, object member)
        {
            if (member is TMember)
            {
                Insert(index,(TMember)member);
            }
        }
    }
}
